package com.quyang.voice.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.*;

import javax.servlet.http.HttpServletRequest;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;

public class JsonUtil implements Serializable {
	private static final long serialVersionUID = -5387655719541888064L;

	public static String objToJsonString(Object obj) {
		try {
			if (obj instanceof JSONObject) {
				return obj.toString();
			}
			return JSON.toJSONString(obj);
		} catch (Exception e) {
			return null;
		}
	}

	public static <T> T stringToTObj(String objectStr, Class<T> t) {
		try {
			if (StringUtils.isBlank(objectStr) || t == null) {
				return null;
			}
			return JSON.parseObject(objectStr, t);
		} catch (Exception e) {
			return null;
		}
	}

	public static Object[] stringToObject(String objectStr) {
		try {
			if (StringUtils.isBlank(objectStr)) {
				return null;
			}
			return JSONObject.parseArray(objectStr, Object.class).toArray();
		} catch (Exception e) {
			return null;
		}
	}

	public static JSONObject stringToJSONObject(String objectStr) {
		try {
			if (StringUtils.isBlank(objectStr)) {
				return null;
			}
			return JSONObject.parseObject(objectStr);
		} catch (Exception e) {
			return null;
		}
	}

	private JsonUtil() {
	}

	private static Gson gson = null;
	static {
		if (gson == null) {
			gson = new Gson();
		}
	}

	/**
	 * 将对象转换成json格式
	 * 
	 * @param ts
	 * @return
	 */
	public static String objectToJson(Object ts) {
		String jsonStr = null;
		if (gson != null) {
			jsonStr = gson.toJson(ts);
		}
		return jsonStr;
	}

	/**
	 * 将对象转换成json格式(并自定义日期格式)
	 * 
	 * @param ts
	 * @return
	 */
	public static String objectToJsonDateSerializer(Object ts,
			final String dateformat) {
		String jsonStr = null;
		gson = new GsonBuilder()
				.registerTypeHierarchyAdapter(Date.class,
						new JsonSerializer<Date>() {
							public JsonElement serialize(Date src,
									Type typeOfSrc,
									JsonSerializationContext context) {
								SimpleDateFormat format = new SimpleDateFormat(
										dateformat);
								return new JsonPrimitive(format.format(src));
							}
						}).setDateFormat(dateformat).create();
		if (gson != null) {
			jsonStr = gson.toJson(ts);
		}
		return jsonStr;
	}

	/**
	 * 将对象转换成json格式(时间转成毫秒数)
	 * 
	 * @param ts
	 * @return
	 */
	public static String objectToJsonDateSerializer(Object ts) {
		String jsonStr = null;
		gson = new GsonBuilder().registerTypeHierarchyAdapter(Date.class,
				new JsonSerializer<Date>() {
					public JsonElement serialize(Date src, Type typeOfSrc,
							JsonSerializationContext context) {
						String s = src.getTime() + "";
						return new JsonPrimitive(s);
					}
				}).create();
		if (gson != null) {
			jsonStr = gson.toJson(ts).replace("\\", "");// 去掉'/'
		}
		return jsonStr;
	}

	public static Object formJsonToObject(String str, Type type) {
		if (gson != null) {
			return gson.fromJson(str, type);
		}
		return null;
	}

	public static <T extends Object> HashMap<String, Object> jsonStrToMap(
			String jsonStr, Class<T> clazz) {
		HashMap<String, Object> map = null;
		if (StringUtils.isBlank(jsonStr) || clazz == null) {
			return map;
		}
		try {
			JSONObject jsonObject = JsonUtil.stringToJSONObject(jsonStr);
			if (jsonObject == null || jsonObject.isEmpty()) {
				return map;
			}
			map = new HashMap<String, Object>();
			for (String key : jsonObject.keySet()) {
				if (StringUtils.isNotBlank(key)) {
					Field field = clazz.getDeclaredField(key.trim());
					if (field != null) {
						Class<?> type = field.getType();
						if (type == Byte.class) {
							map.put(key, jsonObject.getByte(key));
						} else if (type == Short.class) {
							map.put(key, jsonObject.getShort(key));
						} else if (type == Character.class) {
							map.put(key, jsonObject.getString(key));
						} else if (type == Integer.class) {
							map.put(key, jsonObject.getInteger(key));
						} else if (type == Long.class) {
							map.put(key, jsonObject.getLong(key));
						} else if (type == Float.class) {
							map.put(key, jsonObject.getFloat(key));
						} else if (type == Double.class) {
							map.put(key, jsonObject.getDouble(key));
						} else {
							map.put(key, jsonObject.getString(key));
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

	public static <T> T jsonToTObj(JSONObject jsonObject, Class<T> t) {
		try {
			if (jsonObject == null || t == null) {
				return null;
			}
			return JSON.parseObject(jsonObject.toJSONString(), t);
		} catch (Exception e) {
			return null;
		}
	}

	public static String object2json(Object obj) {
		StringBuilder json = new StringBuilder();
		if (obj == null) {
			json.append("\"\"");
		} else if (obj instanceof String || obj instanceof Integer
				|| obj instanceof Float || obj instanceof Boolean
				|| obj instanceof Short || obj instanceof Double
				|| obj instanceof Long || obj instanceof BigDecimal
				|| obj instanceof BigInteger || obj instanceof Byte) {
			json.append("\"").append(string2json(obj.toString())).append("\"");
		} else if (obj instanceof Object[]) {
			json.append(array2json((Object[]) obj));
		} else if (obj instanceof List) {
			json.append(list2json((List<?>) obj));
		} else if (obj instanceof Map) {
			json.append(map2json((Map<?, ?>) obj));
		} else if (obj instanceof Set) {
			json.append(set2json((Set<?>) obj));
		} else {
			json.append(bean2json(obj));
		}
		return json.toString();
	}

	public static String object2json_liger(Object obj, int total) {
		StringBuilder json = new StringBuilder();
		if (obj == null) {
			json.append("\"\"");
		} else if (obj instanceof String || obj instanceof Integer
				|| obj instanceof Float || obj instanceof Boolean
				|| obj instanceof Short || obj instanceof Double
				|| obj instanceof Long || obj instanceof BigDecimal
				|| obj instanceof BigInteger || obj instanceof Byte) {
			json.append("\"").append(string2json(obj.toString())).append("\"");
		} else if (obj instanceof Object[]) {
			json.append(array2json((Object[]) obj));
		} else if (obj instanceof List) {
			json.append(list2json((List<?>) obj));
		} else if (obj instanceof Map) {
			json.append(map2json((Map<?, ?>) obj));
		} else if (obj instanceof Set) {
			json.append(set2json((Set<?>) obj));
		} else {
			json.append(bean2json(obj));
		}

		return "{Rows:[" + json.toString() + "],Total:" + total + "}";
	}

	public static String list2json_liger(List<?> list, int total) {
		StringBuilder json = new StringBuilder();
		json.append("[");
		if (list != null && list.size() > 0) {
			for (Object obj : list) {
				json.append(object2json(obj));
				json.append(",");
			}
			json.setCharAt(json.length() - 1, ']');
		} else {
			json.append("]");
		}

		return "{Rows:" + json.toString() + ",Total:" + total + "}";
	}

	public static String bean2json(Object bean) {
		StringBuilder json = new StringBuilder();
		json.append("{");
		PropertyDescriptor[] props = null;
		try {
			props = Introspector.getBeanInfo(bean.getClass(), Object.class)
					.getPropertyDescriptors();
		} catch (IntrospectionException e) {
		}
		if (props != null) {
			for (int i = 0; i < props.length; i++) {
				try {
					String name = object2json(props[i].getName());
					String value = object2json(props[i].getReadMethod().invoke(
							bean));
					json.append(name);
					json.append(":");
					json.append(value);
					json.append(",");
				} catch (Exception e) {
				}
			}
			json.setCharAt(json.length() - 1, '}');
		} else {
			json.append("}");
		}
		return json.toString();
	}

	public static String list2json(List<?> list) {
		StringBuilder json = new StringBuilder();
		json.append("[");
		if (list != null && list.size() > 0) {
			for (Object obj : list) {
				json.append(object2json(obj));
				json.append(",");
			}
			json.setCharAt(json.length() - 1, ']');
		} else {
			json.append("]");
		}
		return json.toString();
	}

	public static String array2json(Object[] array) {
		StringBuilder json = new StringBuilder();
		json.append("[");
		if (array != null && array.length > 0) {
			for (Object obj : array) {
				json.append(object2json(obj));
				json.append(",");
			}
			json.setCharAt(json.length() - 1, ']');
		} else {
			json.append("]");
		}
		return json.toString();
	}

	public static String map2json(Map<?, ?> map) {
		StringBuilder json = new StringBuilder();
		json.append("{");
		if (map != null && map.size() > 0) {
			for (Object key : map.keySet()) {
				json.append(object2json(key));
				json.append(":");
				json.append(object2json(map.get(key)));
				json.append(",");
			}
			json.setCharAt(json.length() - 1, '}');
		} else {
			json.append("}");
		}
		return json.toString();
	}

	public static String set2json(Set<?> set) {
		StringBuilder json = new StringBuilder();
		json.append("[");
		if (set != null && set.size() > 0) {
			for (Object obj : set) {
				json.append(object2json(obj));
				json.append(",");
			}
			json.setCharAt(json.length() - 1, ']');
		} else {
			json.append("]");
		}
		return json.toString();
	}

	public static String string2json(String s) {
		if (s == null)
			return "";
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < s.length(); i++) {
			char ch = s.charAt(i);
			switch (ch) {
			case '"':
				sb.append("\\\"");
				break;
			case '\\':
				sb.append("\\\\");
				break;
			case '\b':
				sb.append("\\b");
				break;
			case '\f':
				sb.append("\\f");
				break;
			case '\n':
				sb.append("\\n");
				break;
			case '\r':
				sb.append("\\r");
				break;
			case '\t':
				sb.append("\\t");
				break;
			case '/':
				sb.append("\\/");
				break;
			default:
				if (ch >= '\u0000' && ch <= '\u001F') {
					String ss = Integer.toHexString(ch);
					sb.append("\\u");
					for (int k = 0; k < 4 - ss.length(); k++) {
						sb.append('0');
					}
					sb.append(ss.toUpperCase());
				} else {
					sb.append(ch);
				}
			}
		}
		return sb.toString();
	}

	 public static String getReciveData(HttpServletRequest request){
		 String inputLine = "";
		 StringBuffer recieveData = new StringBuffer();
 		BufferedReader in = null;
 		try {
 			in = new BufferedReader(new InputStreamReader(request
 					.getInputStream(), "UTF-8"));
		while ((inputLine = in.readLine()) != null) {
 				recieveData.append(inputLine);
 			}
 		} catch (IOException e) {
 		} finally {
 			try {
 				if (null != in) {
 					in.close();
 				}
 			} catch (IOException e) {
 			}
 		}
 		
 		return recieveData.toString();
     }
	
	public static void main(String[] args) {

//		String str = "{\"result\":\"success\",\"data\":{\"url\":\"http://iyoyo.b0.upaiyun.com/images/20141229/c4e1e7b21c334406a5a509d1ec79f1c8.bmp\",\"prompt\":\"李叔叔打算购买一套新房在咨询的过程中他发现如果分期付款购买要加价15%如果一次性付清房款可优惠10%这样分期付款比现金购买多付16万元这套房子原价多少万元\"},\"status\":\"0\"}";
//		Map<String, Object> map = new HashMap<String, Object>();
//		System.out.println(map.get("data"));
		
//		OrderJson json = new OrderJson();
//		OrderShopJson json2 = new OrderShopJson();
//		OrderShopJson json5 = new OrderShopJson();
//		OrderCargoJson json3 = new OrderCargoJson();
//		OrderCargoJson json4 = new OrderCargoJson();
//		List<OrderCargoJson> list = new ArrayList<OrderCargoJson>();
//		List<OrderCargoJson> list2 = new ArrayList<OrderCargoJson>();
//		json3.setCargoId(1);
//		json3.setCount(2);
//		json3.setDesc("颜色:黑色;机型:test1");
//		json3.setType(0);
//		list.add(json3);
//		
//		json4.setCargoId(2);
//		json4.setCount(1);
//		json4.setDesc("颜色:黑色;机型:test1");
//		json4.setType(0);
//		list2.add(json4);
//		
//		json2.setShopId(1);
//		json2.setCargoJsonList(list);
//		
//		json5.setShopId(2);
//		json5.setCargoJsonList(list2);
//		
//		
//		List<OrderShopJson> list3 = new ArrayList<OrderShopJson>();
//		list3.add(json2);
//		list3.add(json5);
//		
//		json.setOrderShopJsonList(list3);
//		json.setUserId(14);
//		
//		System.out.println(object2json(json));
		
		
	}
	
}

